package me.hunche.app.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import me.hunche.app.dao.SMSDao;
import me.hunche.app.domain.SMS;
import me.hunche.app.service.SMSService;
import me.hunche.app.sms.SMSHandler;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import com.hp.hpl.helper.misc.DateHelper;
import com.hp.hpl.helper.misc.WebServiceHelper;

//@Service
public class WebChineseSMSService implements SMSService,DisposableBean,InitializingBean{
	
	private static final Logger logger = Logger.getLogger(WebChineseSMSService.class);
	private static final String pfile = "/webchinese.properties";
	@Autowired private SMSDao smsDao;
	
	private Integer queryInterval = 60; //n seconds
	private Integer timeout;
	private Map<String,SMSHandler> hds = new HashMap<String,SMSHandler>();
//	@Autowired private SMSHandler hd;
	
	private Properties p = new Properties();
	private Timer timer;
	
	public void afterPropertiesSet() throws Exception {
		timer = new Timer();
		timer.schedule(new QueryMT(), queryInterval*1000, queryInterval*1000);
	}
	
	public class QueryMT extends TimerTask{
		public void run() {
			receiveMessage();
		}
	}

	public void destroy() throws Exception {
		timer.cancel();
		timer = null;
	}

	public WebChineseSMSService(){
		loadProperties();
	}
	
	protected void loadProperties() {
		try {
			p.load(WebChineseSMSService.class.getResourceAsStream(pfile));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	protected String getUid(){
		return p.getProperty("webchinese.uid");
	}
	
	protected String getAccessKey(){
		return p.getProperty("webchinese.accesskey");
	}
	
//	@Override
	public void sendMessage(List<String> recipients, String content) {
//		StringBuffer smsMob = new StringBuffer();
//		for(String r:recipients){
//			smsMob.append(r);
//			smsMob.append(",");
//		}
//		
//		smsMob.deleteCharAt(smsMob.length()-1);
		Collections.shuffle(recipients);
		for(String r:recipients){
			sendMessage(r,content);
		}
	}

	public void sendMessage(String[] recipients, String content) {
		
//		StringBuffer smsMob = new StringBuffer();
//		for(String r:recipients){
//			smsMob.append(r);
//			smsMob.append(",");
//		}
//		
//		smsMob.deleteCharAt(smsMob.length()-1);
//		sendMessage(smsMob.toString(),content);
		
		List list = Arrays.asList(recipients);
		sendMessage(list,content);
	}
	
	public void sendMessage(String mobiles,String content) {
		postMessage(mobiles,content);
	}
	
	public void postMessage(String smsMob,String content) {
		if (logger.isDebugEnabled()) {
			logger.debug("postMessage smsMob=" + smsMob + ",content=" + content + "- start");
		}
		Map<String,String> p = new HashMap();
		p.put("Uid", getUid());
		p.put("Key", getAccessKey());
		p.put("smsMob", smsMob);
		p.put("smsText", content);
		try {
			String json = WebServiceHelper.postJsonRequest("http://utf8.sms.webchinese.cn", p, 30*1000, 30*1000);
			System.out.println(json);
			//TODO 字段长度
			smsDao.save(new SMS(smsMob,content,SMS.TYPE_MT,DateHelper.now()));
		} catch (Exception e) {
			// TODO: handle exception
		}
//		
//		HttpClientUtil httpClientUtil = new HttpClientUtil("http://utf8.sms.webchinese.cn");
//		httpClientUtil.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//		httpClientUtil.addParam("Uid", getUid());
//		httpClientUtil.addParam("Key", getAccessKey());
//		httpClientUtil.addParam("smsMob", smsMob.toString());
//		httpClientUtil.addParam("smsText", content);
//		try {
//			httpClientUtil.execute(ResuestMethod.POST);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		
		if (logger.isInfoEnabled()) {
			logger.info("postMessage smsMob=" + smsMob + ",content=" + content + "- end");
		}
	}

	
	/**
	 * <?xml version="1.0" encoding="UTF-8" ?>
		<delivers>
		<deliver>
		<mob>138000000002</mob>
		<content>回复2</content>
		<time>2010-01-02 15:26:42</time>
		</deliver>
		<deliver>
		<mob>138000000001</mob>
		<content>回复1</content>
		<time>2010-01-01 15:26:42</time>
		</deliver>
		...'多条回复
		</delivers>
	 * 
	 * 
	 * @author admin
	 *
	 */
	public List<SMS> receiveMessage() {
//		if (logger.isInfoEnabled()) {
//				logger.info("receiveMessage");
//			}
		
		Map p = new HashMap();
		p.put("Action", "UP");
		p.put("Uid", getUid());
		p.put("Key", getAccessKey());
		p.put("Prompt", "1");
		
		String resp = WebServiceHelper.getJsonResponse("http://sms.webchinese.cn/web_api/SMS/", p,  30*1000, 30*1000);
		if(resp.startsWith("<")){
			try {  
	            SAXReader reader = new SAXReader();  
	            Document doc = DocumentHelper.parseText(resp);   
	            Element root = doc.getRootElement();
	            if(root.elements()!=null && !root.elements().isEmpty()){
	            	List<SMS> ms = new ArrayList();	
	            	for(int i=root.elements().size()-1;i>=0;i--){
	            		Element v = (Element)root.elements().get(i);
	            		String mobile = v.element("mob").getTextTrim();
	            		String content = v.element("content").getTextTrim();
	            		String stime = v.element("time").getTextTrim();
	            		Date dtime = DateHelper.toTimestamp(stime, DateHelper.YYYY_MM_DD_HH_MM_SS);
	            		
	            		for(Entry<String, SMSHandler> item:hds.entrySet()){
	            			if(content!=null && content.toUpperCase().startsWith(item.getKey())){
	            				item.getValue().execute(mobile, content);
	            			}
	            			ms.add(new SMS(mobile,content,SMS.TYPE_MO,dtime));
	            			if (logger.isInfoEnabled()) {
	         					logger.info("Received message "+mobile +" "+content +" "+stime);
	         				}
	            		}
	            	}
	            	smsDao.saves(ms);
	            	return ms;
	            }
	          
	        } catch (Exception e) {
	        	System.out.println(resp);
	            e.printStackTrace();  
	        }
		}
		return null;
	}


	public void registerHandler(SMSHandler handler) {
		logger.info("registerHandler "+handler.getPrefix().toUpperCase() +" "+handler.getClass().getName());
		hds.put(handler.getPrefix().toUpperCase(), handler);
	}

	public void sendScheduledMessage(final List<String> recipients, final String content,Date sendTime) {
		timer.schedule(new TimerTask() {
			public void run() {
				sendMessage(recipients, content);
			}
		}, sendTime);
	}

	public void sendScheduledMessage(final String recipient,final String content,
			Date sendTime) {
		timer.schedule(new TimerTask() {
			public void run() {
				sendMessage(recipient, content);
			}
		}, sendTime);
	}
}
